#include "HiredisClient.h"
#include "HiredisSubscriber.h"

#include <chrono>
#include <cstring>
#include <hiredis/async.h>
#include <hiredis/hiredis.h>
#include <hiredis/read.h>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
using namespace std;

#include <glog/logging.h>

int redis_sync_example();
int redis_async_example();

int main(int argc, char *argv[])
{
    // redis_sync_example();
    redis_async_example();
    return 0;
}

int redis_sync_example()
{
    HiredisClient ctx("127.0.0.1", 6379);
    if (!ctx.connect()) {
        LOG(ERROR) << "Redis 连接失败";
        return -1;
    }

#if 0
    {
        std::shared_ptr<redisReply> reply = ctx.execute("SET runoobkey %s", "redis");
        if (!reply || reply->type == REDIS_REPLY_ERROR) {
            if (reply) {
                std::cout << "reply error: " << reply->str << std::endl;
            } else {
                std::cout << "error create reply" << std::endl;
            }
            return -1;
        }

        if (reply->type == REDIS_REPLY_STATUS) {
            std::cout << "status: " << reply->str << std::endl;
        }
    }
#endif

    {
        if (ctx.execute("SUBSCRIBE test")) {
            auto reply = ctx.getReply();
            if (!reply || reply->type == REDIS_REPLY_ERROR) {
                if (reply) {
                    LOG(ERROR) << "reply error: " << reply->str;
                } else {
                    LOG(ERROR) << "error create reply";
                }
            }
            if (reply && reply->type == REDIS_REPLY_STATUS) {
                LOG(INFO) << "status: " << reply->str;
            }
        }
    }

    int i = 0;
    while (true) {
        std::cout << "*********************************************" << std::endl;
        auto reply = ctx.getReply();
        if (reply && reply->type == REDIS_REPLY_ARRAY) {
            for (int i = 0; i < reply->elements; i++) {
                LOG(INFO) << "get reply: " << reply->element[i]->str;
            }
        } else {
            LOG(INFO) << "get reply type: " << reply->type;
        }
    }
}

int redis_async_example()
{
    HiredisSubscriber subscriber;
    subscriber.init("127.0.0.1", 6379);
    subscriber.run({"test"}, [](const std::string &channel, const std::string &message) {
        LOG(INFO) << channel << ": " << message;
    });

    return 0;
}